#include "widget.h"
#include "ui_widget.h"
#include "login.h"
#include <QStandardItemModel>
#include <QMessageBox>
#include <QTimer>
#include <QBuffer>
#include "LabelUtils.h"
#include "FFmpegProcessor.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
    , tcpSocket(nullptr)
{
    ui->setupUi(this);
    ui->receiveMsg->setReadOnly(true);
    ui->widget_3->setStyleSheet("QWidget { background-color: white; border: 1px solid black; }");
    ui->msgEdit->setStyleSheet("QTextEdit { border: none; }");

    connect(ui->returnBtn, &QPushButton::clicked, this, &Widget::click_returnBtn);
    connect(ui->pushButton, &QPushButton::clicked, this, &Widget::click_sendBtn);
    connect(ui->userList, &QListWidget::itemClicked, this, &Widget::onFriendClicked);
    connect(ui->openCamera, &QPushButton::clicked, this, &Widget::on_startButton_clicked);
    connect(ui->targetUserClick, &QPushButton::clicked, this, &Widget::on_setTargetButton_clicked);
    //初始本地音频播放
    // 初始化音频输出设备 (Qt6 使用 QAudioSink)
    QAudioFormat format;
    format.setSampleRate(16000);
    format.setChannelCount(1);
    format.setSampleFormat(QAudioFormat::Int16);

    // 获取默认音频输出设备
    QAudioDevice outputDevice = QMediaDevices::defaultAudioOutput();
    if (!outputDevice.isFormatSupported(format)) {
        qDebug() << "默认输出设备不支持该格式，使用设备推荐格式";
        format = outputDevice.preferredFormat();
    }

    // 创建 QAudioSink 实例
    audioSink = new QAudioSink(outputDevice, format, this);
    audioOutputDevice = audioSink->start(); // 启动输出设备

}

Widget::~Widget()
{
    if (tcpSocket) tcpSocket->deleteLater();
    // 1. 停止音频输入
    if (audioInput) {
        audioInput->stop();
        delete audioInput;
        audioInput = nullptr;
    }

    // 2. 停止音频输出
    if (audioSink) {
        audioSink->stop();
        delete audioSink;
        audioSink = nullptr;
    }
    audioOutputDevice = nullptr; // 显式置空

    // 3. 关闭网络连接
    if (udpSocket) {
        udpSocket->close();
        udpSocket->deleteLater();
        udpSocket = nullptr;
    }
    delete ui;
}

void Widget::click_returnBtn()
{
    // 断开 TCP 连接
    if (tcpSocket) {
        tcpSocket->disconnectFromHost();  // 断开连接
        tcpSocket->waitForDisconnected(3000);  // 等待最多 3 秒直到连接断开
        tcpSocket->deleteLater();  // 确保 tcpSocket 被销毁
    }

    // 关闭当前窗口
    this->close();

    // 创建新的登录窗口并显示
    Login *log = new Login();
    log->show();
}
void Widget::click_sendBtn()
{
    if (!tcpSocket || !tcpSocket->isValid() || tcpSocket->state() != QAbstractSocket::ConnectedState) {
        qDebug() << "未连接到服务器，无法发送消息";
        return;
    }

    // 获取输入框中的消息（支持富文本）
    QString message = ui->msgEdit->toPlainText();  // 使用 toHtml() 获取富文本内容
    if (message.isEmpty()) {
        qDebug() << "消息不能为空";
        return;
    }

    // 将消息发送到服务器
    tcpSocket->write(message.toUtf8() + "\n");
    tcpSocket->flush();

    // 在本地的 receiveMsg 控件中显示自己的消息
    QString localMessage = QString("[我]: %1").arg(message);
    ui->receiveMsg->append(localMessage);

    // 清空输入框
    ui->msgEdit->clear();
}

void Widget::setTcpSocket(QTcpSocket* socket, QString name)
{
    // 初始化视频
    if (!QMediaDevices::videoInputs().isEmpty()) {
        camera = new QCamera(QMediaDevices::defaultVideoInput());
        captureSession = new QMediaCaptureSession(this);
        captureSession->setCamera(camera);

        videoSink = new QVideoSink(this);
        captureSession->setVideoSink(videoSink);
        connect(videoSink, &QVideoSink::videoFrameChanged, this, &Widget::handleFrame);

        const auto formats = camera->cameraDevice().videoFormats();
        if (!formats.isEmpty()) camera->setCameraFormat(formats.first());
    }

    // 初始化音频
    QAudioFormat format;
    // 优先使用设备推荐格式
    format = QMediaDevices::defaultAudioInput().preferredFormat();

    // 或尝试通用设置
    if (format.sampleRate() == -1) {
        format.setSampleRate(16000);  // 优先尝试48kHz
        format.setChannelCount(1);    // 优先立体声
        format.setSampleFormat(QAudioFormat::Int16);
    }

    qDebug() << "尝试使用的音频格式:";
    qDebug() << "  采样率:" << format.sampleRate();
    qDebug() << "  声道数:" << format.channelCount();
    qDebug() << "  采样格式:" << format.sampleFormat();

    if (QMediaDevices::defaultAudioInput().isFormatSupported(format)) {
        audioInput = new QAudioSource(format, this);
        qDebug() << "音频输入初始化成功";
    } else {
        qDebug() << "格式不支持！推荐的设备格式为:";
        auto deviceFormat = QMediaDevices::defaultAudioInput().preferredFormat();
        qDebug() << "  采样率:" << deviceFormat.sampleRate();
        qDebug() << "  声道数:" << deviceFormat.channelCount();
        qDebug() << "  采样格式:" << deviceFormat.sampleFormat();
    }
    if (!audioInput) {
        qDebug() << "audioInput 初始化失败！";
        return;
    }

    // 初始化网络
    udpSocket = new QUdpSocket(this);
    if (!udpSocket->bind(QHostAddress::Any, 0)) {
        qDebug() << "udp端口绑定失败";
    }else{
        randomPort = udpSocket->localPort();
        qDebug() << "成功绑定到随机端口：" << randomPort;
    }
    connect(udpSocket, &QUdpSocket::readyRead, this, &Widget::processDatagram);

    // 注册用户
    QByteArray data = "REGISTER " + name.toUtf8();
    udpSocket->writeDatagram(data, targetAddress, targetPort);

    tcpSocket = socket;
    myname = name;
    ui->myname->setText(myname);
    if (tcpSocket) connect(tcpSocket, &QTcpSocket::readyRead, this, &Widget::onReadyRead);
}


void Widget::showAutoCloseMessageBox(const QString &message, int timeout = 3000, QWidget *parent = nullptr) {
    QMessageBox *msgBox = new QMessageBox(QMessageBox::Information,
                                          "提示",
                                          message,
                                          QMessageBox::NoButton,
                                          parent);
    msgBox->setAttribute(Qt::WA_DeleteOnClose); // 确保消息框在关闭后自动删除
    msgBox->setModal(false); // 设置为非模态，避免阻塞主窗口
    QTimer::singleShot(timeout, msgBox, SLOT(close())); // 在指定时间后自动关闭消息框
    msgBox->show();
}
void Widget::onReadyRead() {
    qDebug() << "Widget::onReadyRead 被调用";
    if (!tcpSocket) {
        qDebug() << "TCP Socket 未初始化";
        return;
    }

    QByteArray data = tcpSocket->readAll();
    QString receivedMessage = QString::fromUtf8(data);

    // 检查是否是在线用户列表
    if (receivedMessage.startsWith("在线用户: ")) {
        QStringList onlineUsers = receivedMessage.split(" ");
        onlineUsers.removeFirst();  // 移除"在线用户: "
        onlineUsers.removeLast();   // 移除最后的换行符
        ui->userList->clear();      // 清空当前用户列表
        for (const QString& user : onlineUsers) {
            LabelUtils::addFriend(ui->userList, user, ":/icons/default_icon.png");
        }
    }
    // 检查是否是用户加入的消息
    else if (receivedMessage.contains("加入了聊天室")) {
        QString username = receivedMessage.split(" ").first();  // 提取用户名
        qDebug() << "用户加入：" << username;

        // 添加用户到好友列表
        LabelUtils::addFriend(ui->userList, username, ":/icons/default_icon.png");
    }
    // 检查是否是用户离开的消息
    else if (receivedMessage.contains("离开了聊天室")) {
        QString username = receivedMessage.split(" ").first();  // 提取用户名
        qDebug() << "用户离开：" << username;

        // 删除用户从好友列表
        LabelUtils::removeFriend(ui->userList, username);
    }
    else {
        // 解析普通消息格式：[发送者用户名]: 消息内容
        QRegularExpression regex(R"(\[([^\]]+)\]:\s*(.*))");
        QRegularExpressionMatch match = regex.match(receivedMessage);
        if (match.hasMatch()) {
            QString sender = match.captured(1);  // 发送者用户名
            QString messageContent = match.captured(2);  // 消息内容

            // 将收到的消息显示在接收框中
            ui->receiveMsg->append(receivedMessage.trimmed());

            // 在消息编辑框中显示发送者的用户名
            if (ui->msgEdit->toPlainText().isEmpty()) {
                ui->msgEdit->setText(sender + ": ");
            }
        } else {
            qDebug() << "收到的消息格式不正确：" << receivedMessage;
            ui->receiveMsg->append(receivedMessage.trimmed());  // 显示原始消息
        }
    }
}
void Widget::onFriendClicked(QListWidgetItem* item) {
    if (!item) return;  // 防止空指针

    // 获取自定义项的QWidget
    QWidget* customWidget = static_cast<QWidget*>(ui->userList->itemWidget(item));
    if (!customWidget) return;

    // 通过objectName查找QLabel
    QLabel* nameLabel = customWidget->findChild<QLabel*>("nameLabel");
    if (!nameLabel) return;

    // 获取好友名字并更新消息窗口
    QString friendName = nameLabel->text();
    ui->msgEdit->setText(friendName + ":");
    ui->targetUserName->setText(friendName);
}
//视屏通话设置
void Widget::on_startButton_clicked() {
    if (camera->isActive()) {
        camera->stop();
        ui->openCamera->setText("启动摄像头");

    } else {
        camera->start();
        ui->openCamera->setText("停止摄像头");
        showAutoCloseMessageBox("启动成功"+targetUser, 3000, this);

    }
    //音频发送逻辑
    if (!isAudioActive) {
        audioIODevice = audioInput->start();
        if (!audioIODevice) {
            qDebug() << "音频设备启动失败！";
            return;
        }

        connect(audioIODevice, &QIODevice::readyRead, this, &Widget::handleAudioData);
        qDebug() << "开始发送音频数据";
    } else {
        audioInput->stop();
        audioIODevice->disconnect();
    }
    isAudioActive = !isAudioActive;
}
void Widget::on_setTargetButton_clicked() {
    targetUser = ui->targetUserName->text();
    qDebug() << "目标用户设置为:" << targetUser;
    showAutoCloseMessageBox("目标设置为"+targetUser, 3000, this);
}
void Widget::handleFrame(const QVideoFrame &frame)
{
    QImage image = frame.toImage();
    if (image.isNull()) return;

    QByteArray imgData;
    QBuffer buffer(&imgData);
    if (buffer.open(QIODevice::WriteOnly)) {
        image.save(&buffer, "JPEG", 20);
        buffer.close();
        qDebug() << "图像压缩前:"<<imgData.size();
        sendMediaData("TARGET:", imgData);
    }
    // QByteArray encoded = FFmpegProcessor::instance().encodeVideo(frame);
    // if(!encoded.isEmpty()) {
    //     sendMediaData("TARGET:", encoded);
    //     qDebug() << "图像压缩后:"<<encoded.size();//示例：图像压缩后: 406
    // }
}
void Widget::handleAudioData()
{
    // 1. 检查是否有有效数据
    if (!audioIODevice || audioIODevice->bytesAvailable() <= 0)
        return;

    // 2. 读取音频数据
    //QByteArray audioData = audioIODevice->readAll();
    QByteArray audioData = audioIODevice->readAll();
    // 3. 示例处理：打印数据信息
    //qDebug() << "发送音频数据 - 大小:" << audioData.size();

    // 4. 发送到网络（示例）
    if (!targetUser.isEmpty()) {
        sendMediaData("SYTARGET:", audioData);
    }

    // QByteArray pcm = audioIODevice->readAll();
    // QByteArray encoded = FFmpegProcessor::instance().encodeAudio(pcm,
    //                                                              pcm.size() / (av_get_bytes_per_sample(AV_SAMPLE_FMT_S16)));
    // if(!encoded.isEmpty()) {
    //     sendMediaData("AUDIO:", encoded);
    // }
}
void Widget::sendMediaData(const QByteArray& prefix, const QByteArray& data)
{
    if (targetUser.isEmpty()) return;

    QByteArray header = prefix + targetUser.toUtf8() + "\n";
    QByteArray packet = header + data;
    if (udpSocket) {
        udpSocket->writeDatagram(packet, targetAddress, targetPort);
    }
}
void Widget::processDatagram() {
    while (udpSocket->hasPendingDatagrams()) {
        QNetworkDatagram datagram = udpSocket->receiveDatagram();
        QByteArray data = datagram.data();
        if (data == "REGISTER_OK") {
            isRegistered = true;
            qDebug() << "注册成功";
            showAutoCloseMessageBox("注册成功", 3000, this);
        } else if (data.startsWith("REGISTER_FAIL")) {
            qDebug() << "注册失败";
            showAutoCloseMessageBox("注册失败", 3000, this);
        } else if (data.startsWith("SET_TARGET_FAIL")) {
            qDebug() << "目标设置失败";
        } else {
            receiveImageData(data);
        }
    }
}
void Widget::receiveImageData(const QByteArray &datagram) {
    // 修改音频数据接收处理部分：
    if (datagram.startsWith("SY")) {
        QByteArray audioData = datagram.mid(2);
        //qDebug() << "接收音频数据长度:" << audioData.size();

        // 检查输出设备状态，必要时重新启动
        if (!audioSink || audioSink->state() == QAudio::StoppedState) {
            qDebug() << "音频输出设备未活动，重新启动...";
            if (audioSink) {
                audioSink->stop();
                delete audioSink;
            }
            QAudioFormat format = QMediaDevices::defaultAudioOutput().preferredFormat();
            audioSink = new QAudioSink(format, this);
            audioOutputDevice = audioSink->start();
        }

        if (audioOutputDevice && audioOutputDevice->isOpen()) {
            audioOutputDevice->write(audioData);
        }
        return;
    }
    // qDebug() << "接收图像:" << datagram.size();//示例：接收图像: 406
    // QByteArray decodedData = FFmpegProcessor::instance().decodeVideo(datagram);
    // if (!decodedData.isEmpty()) {
    //     // 显示图像
    //     QImage image(reinterpret_cast<const uchar*>(decodedData.data()), 640, 480, QImage::Format_RGB32);
    //     ui->targetUser->setPixmap(QPixmap::fromImage(image));
    // } else {
    //     qDebug() << "视频帧解码失败";
    // }
    QImage image;
    if (image.loadFromData(datagram)) {
        QPixmap pixmap = QPixmap::fromImage(image);
        if (!pixmap.isNull()) {
            QMetaObject::invokeMethod(this, [this, pixmap]() {
                ui->targetUser->setPixmap(pixmap.scaled(ui->targetUser->size(), Qt::KeepAspectRatio));
            }, Qt::QueuedConnection);
        } else {
            qDebug() << "QPixmap 为空，无法设置到 QLabel";
        }
    } else {
        qDebug() << "无法加载图像数据";
    }
}
